package com.sfx.messagequeue.mqServer.core;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.UUID;

/**
 * Created with IntelliJ IDEA.
 * Description:消息队列的 "主角" -> 消息
 * 消息主要包含两个部分 : 消息的核心属性(BasicProperties) 和 消息的正文(具体的消息是啥)(body)
 * User: sfx
 * Date: 2023-07-30
 * Time: 18:24
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
//Message需要实现Serializable-->标准库实现序列化的方式
//便于Message在网络中传输和文件存储
//不使用JACKSON序列化的原因是,它是文本序列化,而我们是二进制序列化
public class Message implements Serializable {
    //basicProperties 和 body是Message最核心的两个属性
    //消息的核心属性
    private BasicProperties basicProperties =  new BasicProperties();
    //消息的正文(具体的消息是啥?)
    private byte[] body;

    //Message还需额外属性来支持持久化功能-->左闭右开[offsetBeg,offsetEnd)
    //通过以下两个偏移量就能在文件中找到具体的消息.

    //两个偏移量不需要存储到硬盘上,因为消息存到文件中就固定了
    //另外我们只需要在内存中知道就可以了,因为我们想要根据内存中的偏移量找到消息在文件中所处的位置即可
    //所以使用transient来修饰,表示不需要被持久化->序列化
    //文件开头距离消息开头的偏移量
    private transient long offsetBeg = 0L;
    //文件开头距离消息结尾的偏移量
    private transient long offsetEnd = 0L;

    //消息是否有效 0x0代表无效,0x1代表有效
    private byte isValid = 0x1;

    //使用工厂方法创建一个消息
    public static Message createMessageWithId(BasicProperties basicProperties, String routingKey, byte[] body) {
        Message message = new Message();
        if(basicProperties != null) {
            message.setBasicProperties(basicProperties);
        }
        //如果传递了RoutingKey,以外边的为主
        message.setRoutingKey(routingKey);
        //设置messageId,使用UUID
        message.setMessageId("M-"+UUID.randomUUID());
        message.setBody(body);
        return message;
    }

    public String getMessageId() {
        return basicProperties.getMessageId();
    }
    public void setMessageId(String messageId) {
        basicProperties.setMessageId(messageId);
    }

    public String getRoutingKey() {
        return basicProperties.getRoutingKey();
    }
    public void setRoutingKey(String routingKey) {
        basicProperties.setRoutingKey(routingKey);
    }

    public int getDeliverMode() {
        return basicProperties.getDeliverMode();
    }
    public void setDeliverMode(int mode) {
        basicProperties.setDeliverMode(mode);
    }
}